package org.transfer.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;

import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;

public class DecompUtils {

	/**
	 * 文件解压7z
	 * 
	 * @param orgPath
	 * @param tarpath
	 */
	public static void decompression7z(String filePath, String outPath) {
		SevenZFile sevenZFile = null;
		FileOutputStream out = null;
		try {
			File file = new File(filePath);
			sevenZFile = new SevenZFile(file);
			SevenZArchiveEntry entry = sevenZFile.getNextEntry();
			while (entry != null) {
				if (!(file.getName().substring(0, file.getName().indexOf("."))
						.equals(entry.getName().substring(0, entry.getName().indexOf("."))))) {
					throw new RuntimeException("解压失败，压缩文件名称不符合规范");
				}
				if (entry.isDirectory()) {
					new File(outPath + entry.getName()).mkdirs();
					entry = sevenZFile.getNextEntry();
					continue;
				}
				out = new FileOutputStream(outPath + File.separator + entry.getName());
				byte[] content = new byte[(int) entry.getSize()];
				sevenZFile.read(content, 0, content.length);
				out.write(content);
				out.close();
				entry = sevenZFile.getNextEntry();
			}
			sevenZFile.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			// 可能不是7z，则用zip方法解压
			decompressionZip(filePath, outPath);
		} finally {
			try {
				if (out != null) {
					out.close();
				}
				if (sevenZFile != null) {
					sevenZFile.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * ZIP解压
	 * 
	 * @param srcFile
	 * @param destPath
	 */
	public static void decompressionZip(String filePath, String outPath) {
		ZipFile zipFile = null;
		try {
			File inputfile = new File(filePath);
			zipFile = new ZipFile(inputfile);
			Enumeration<ZipArchiveEntry> e = zipFile.getEntries();
			while (e.hasMoreElements()) {
				ZipArchiveEntry entry = e.nextElement();
				if (!(inputfile.getName().substring(0, inputfile.getName().indexOf("."))
						.equals(entry.getName().substring(0, entry.getName().indexOf("."))))) {
					throw new RuntimeException("解压失败，压缩文件名称不符合规范");
				}
				File file = new File(outPath, entry.getName());
				if (entry.isDirectory()) {
					file.mkdirs();
				} else {
					InputStream in = zipFile.getInputStream(entry);
					File parent = file.getParentFile();
					if (parent != null && !parent.exists()) {
						parent.mkdirs();
					}
					OutputStream out = new FileOutputStream(file);
					final byte[] buffer = new byte[8 * 1024];
					int len = 0;
					while ((len = in.read(buffer)) != -1) {
						out.write(buffer, 0, len);
					}
					in.close();
					out.close();
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				zipFile.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 批量解压
	 * 
	 * @param filePath
	 * @param outPath
	 */
	public static void decompressionFiles(String filePath, String outPath) {
		File file = new File(filePath);
		File[] files = file.listFiles();
		for (File f : files) {
			if (f.isFile()) {
				System.out.println("------【" + f.getName() + "】开始解压！-------");
				File outFile = new File(outPath);
				if (!outFile.exists()) {
					outFile.mkdirs();
				}
				decompression7z(f.getPath(), outPath);
				System.out.println("------【" + f.getName() + "】开始完毕！-------");
			}
		}
		System.out.println("------全部开始完毕！-------");
	}

	public static void main(String[] args) {
		// 源压缩文件地址
		String orgPath = "F:/project/file/out/";
		// 解压后存放的目录地址
		String tarpath = "F:/project/file/deco/";
		// 开始解压
		decompressionFiles(orgPath, tarpath);

	}
}
